// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "NetComm.h"

#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <thread>

#include <dlfcn.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "HWSecure/include/securec.h"

#include "Communication/Socket/TcpSocket/VmiTcpClientSocket.h"
#include "MemoryManagement/VmiBuffer.h"
#if defined(USE_GL_PACKET_HANDLE)
#include "Communication/PacketHandle/GLPacketHandle.h"
#endif
using namespace std;

#define ID_HEADER "[%u] "
#define NC_INFO(fmt, ...) INFO(ID_HEADER fmt, m_id, ##__VA_ARGS__)
#define NC_ERR(fmt, ...) ERR(ID_HEADER fmt, m_id, ##__VA_ARGS__)

std::mutex NetComm::g_idMutex = {};
uint32_t NetComm::g_nextId = 0;

/**
 * @功能描述：构造函数
 */
/*lint -save -e1401 */
NetComm::NetComm()
    : m_mode(NetComm::CLIENT)
{
    m_pktHandle.fill(nullptr);
    m_id = GenerateId();
}
/*lint -restore */
/**
 * @功能描述：构造函数（Server模式）
 */
NetComm::NetComm(std::shared_ptr<VmiSocket> newSocket, std::function<void(std::shared_ptr<NetComm>)> callback)
    : m_socket(newSocket), m_breakCallback(callback), m_mode(NetComm::SERVER)
{
    m_pktHandle.fill(nullptr);
    m_id = GenerateId();
}

/**
 * @功能描述：析构函数，释放对象
 */
NetComm::~NetComm()
{
    Deinit();
}

/**
 * @功能描述：生成标识
 * @返回值：标识
 */
uint32_t NetComm::GenerateId()
{
    std::unique_lock<std::mutex> lck(g_idMutex);
    uint32_t id = ++g_nextId;
    return id;
}

/**
 * @功能描述：获取标识
 * @返回值：标识
 */
uint32_t NetComm::GetId()
{
    return m_id;
}

/**
 * @功能描述：获取socket句柄
 * @返回值：socket句柄
 */
int NetComm::GetSocketFd()
{
    if (m_socket.get() != nullptr) {
        return m_socket->GetFd();
    } else {
        ERR("m_socket is nullptr");
        return 0;
    }
}

/**
 * @功能描述：设置异常断开回调函数
 */
void NetComm::SetBreakCallback(std::function<void(std::shared_ptr<NetComm>)> callback)
{
    m_breakCallback = callback;
}

/**
 * @功能描述：获取状态
 * @返回值：当前状态（未初始化/已初始化/运行态）
 */
NetCommStatus NetComm::GetStatus()
{
    std::unique_lock<std::mutex> lockGuard(m_lock);
    return m_status;
}

/**
 * @功能描述：设置VmiSocket的状态
 * @参数 [in] status：要设置的socket状态，如断开
 */
void NetComm::SetSocketStatus(int status)
{
    std::unique_lock<std::mutex> lockGuard(m_lock);
    if (m_socket != nullptr) {
        m_socket->SetStatus(status);
        NC_INFO("SetSocketStatus: %d", status);
    }
}

/**
 * @功能描述：设置IP和端口
 * @参数 [in] ip：字符串形式的ip地址
 * @参数 [in] port：端口
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::SetIpAndPort(const std::string& ip, unsigned short port)
{
    std::unique_lock<std::mutex> lockGuard(m_lock);
    m_ip = ip;
    m_port = port;

    struct in_addr addr = {};
    int socketRet = inet_aton(m_ip.c_str(), &addr);
    if (socketRet == 0) {
        NC_ERR("invalid ip, please check ip");
        return false;
    }

    if (m_socket != nullptr) {
        m_socket->SetAddress(ntohl(addr.s_addr), m_port, 0, 0);
    } else {
        NC_ERR("socket is nullptr, set address failed");
        return false;
    }

    return true;
}

/**
 * @功能描述：获取VmiSocket的连接状态
 * @返回值：如果连接着返回true，断开返回false
 */
bool NetComm::GetConnectStatus()
{
    std::unique_lock<std::mutex> lockGuard(m_lock);

    bool ret = false;
    if (m_socket != nullptr) {
        int status = m_socket->GetStatus();
        NC_INFO("GetConnectStatus: %d", status);
        if (status == SOCKET_STATUS_RUNNING) {
            ret = true;
        }
    }
    return ret;
}

/**
 * @功能描述：获取心跳模块记录的loopback平均延迟，反映网络传输状况
 * @返回值：loopback平均延迟
 */
uint64_t NetComm::GetLag()
{
    std::unique_lock<std::mutex> lockGuard(m_lock);

    uint64_t lag = 0;
    if (m_heartbeat != nullptr) {
        lag = m_heartbeat->GetNetLoopbackLatencyAverage();
    }
    return lag;
}

/**
 * @功能描述：创建VmiSocket
 * @返回值：操作成功返回true，失败返回false
 */
bool NetComm::CreateSocket()
{
    m_socket = std::shared_ptr<VmiTcpClientSocket>(new (std::nothrow) VmiTcpClientSocket(0, 0));
    if (m_socket == nullptr) {
        NC_ERR("new VmiTcpClientSocket failed");
        return false;
    }

    NC_INFO("create socket:%p", m_socket.get());
    return true;
}

/**
 * @功能描述：注册处理钩子
 * @参数 [in] type：消息类型
 * @参数 [in] hook：钩子函数地址
 * @参数 [in] isSingleFragment：是否单包发送（不分片）
 * @返回值：操作成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t NetComm::RegisterHook(VMIMsgType type, RENDER_SERVER_HANDLE_HOOK hook, bool isSingleFragment)
{
    if (type <= VMIMsgType::Invalid || type >= VMIMsgType::End) {
        NC_ERR("error: illegal type: %u", type);
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }

    if (m_status != NET_COMM_STATUS_INIT) {
        ERR("error: only allow to register hook in init status, current status is %u", m_status);
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }

    if (m_streamParser != nullptr) {
        auto handle = std::shared_ptr<PacketHandle>(new (std::nothrow) PacketHandle(type, hook, isSingleFragment));
        if (handle == nullptr) {
            NC_ERR("error: create PacketHandle(%u) failed", type);
            return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
        }
        NC_INFO("create PacketHandle(%u) success", type);

        m_streamParser->SetServiceHandle(type, handle);
        m_pktHandle[type] = handle;
        NC_INFO("register hook(%u : %p)", type, hook);
    } else {
        NC_ERR("m_streamParser is nullptr, please do init first");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }

    return VMI_SUCCESS0;
}

#if defined(USE_GL_PACKET_HANDLE)
/**
 * @功能描述：注册GL数据包处理钩子
 * @参数 [in] hook：GL钩子函数地址
 * @参数 [in] isSingleFragment：是否单包（不分片）
 * @返回值：操作成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t NetComm::RegisterGLDataHook(RENDER_SERVER_HANDLE_HOOK hook, bool isSingleFragment)
{
    if (m_status != NET_COMM_STATUS_INIT) {
        ERR("error: only allow to register gl hook in init status, current status is %u", m_status);
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }

    if (m_streamParser != nullptr) {
        auto handle = std::shared_ptr<GLPacketHandle>(new (std::nothrow) GLPacketHandle(hook, isSingleFragment));
        if (handle == nullptr) {
            NC_ERR("error: failed to create GLHandle");
            return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
        }
        NC_INFO("create GLHandle success");
        if (!handle->Init()) {
            NC_ERR("error: failed to init GLHandle");
            return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
        }
        NC_INFO("init GLHandle success");

        m_streamParser->SetServiceHandle(VMIMsgType::GL, handle);
        m_pktHandle[VMIMsgType::GL] = handle;
        NC_INFO("register GL hook(%p)", hook);
    } else {
        NC_ERR("m_streamParser is nullptr, please do init first");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }

    return VMI_SUCCESS0;
}
#endif

/**
 * @功能描述：初始化，根据Hook注册表创建各类型ServiceHandle
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::Init()
{
    NC_INFO("begin to Init");
    std::unique_lock<std::mutex> lockGuard(m_lock);

    if (m_status != NET_COMM_STATUS_UNINIT) {
        NC_INFO("already init!");
        return true;
    }

    bool result = false;
    do {
        if (m_mode == NetComm::CLIENT && !CreateSocket()) {
            NC_ERR("error: create socket failed");
            break;
        }

        m_notice = std::shared_ptr<ClientNotice>(new (std::nothrow) ClientNotice(this));
        if (m_notice == nullptr) {
            NC_ERR("error: create client notice failed");
            break;
        }

        m_streamParser = new (std::nothrow) StreamParse();
        if (m_streamParser == nullptr) {
            NC_ERR("error: create stream parser failed");
            break;
        }

        result = true;
        m_status = NET_COMM_STATUS_INIT;
    } while (0);

    if (!result) {
        NC_ERR("error: Init failed");
        DeinitNoLock();
    }
    NC_INFO("Init successed");
    return result;
}

/**
 * @功能描述：启动解析线程和心跳
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::StartStreamParseAndHeartbeat()
{
    NC_INFO("starting stream parse thread");
    m_streamParseThread = std::unique_ptr<StreamParseThread>(new (std::nothrow) StreamParseThread(m_socket));
    if (m_streamParseThread == nullptr) {
        NC_ERR("error: failed to creat stream parse thread");
        return false;
    }
    m_streamParseThread->SetStreamParse(m_streamParser);

    if (m_heartbeat == nullptr) {
        m_heartbeat = std::shared_ptr<Heartbeat>(new (std::nothrow) Heartbeat(m_socket,
            [this](std::shared_ptr<VmiSocket> breakSocket) -> void {
            NC_INFO("Heartbeat timeout");
            HandleSocketBreak(breakSocket);
        }));

        if (m_heartbeat == nullptr) {
            NC_ERR("error: create hearbeat failed");
            return false;
        }

        if (m_streamParser != nullptr) {
            m_streamParser->SetServiceHandle(VMIMsgType::HEARTBEAT, m_heartbeat);
        }
    }

    if (m_streamParseThread->Start() != 0) {
        NC_ERR("error: start stream parse thread failed");
        return false;
    }
    NC_INFO("stream parse thread started");

    if (!m_heartbeat->Start()) {
        NC_ERR("error: m_heartbeat start failed");
        return false;
    }
    NC_INFO("heartbeart started");

    return true;
}

/**
 * @功能描述：clientNotice构造函数
 */
ClientNotice::ClientNotice(NetComm *netComm)
    : m_netComm(netComm)
{
}

/**
 * @功能描述：clientNotice析构函数
 */
ClientNotice::~ClientNotice()
{
    m_netComm = nullptr;
}//lint !e1540

/**
 * @功能描述：客户端Socket断开通知函数
 * @参数 [in] tcpSocket：客户端socket对象
 */
void ClientNotice::Notice(std::shared_ptr<VmiSocket> tcpSocket)
{
    std::thread noticeThread(
        [this](const std::shared_ptr<VmiSocket> socket) -> void {
            INFO("clientNotice Notice, pTcpSocket error!!!!!!");
            if (m_netComm != nullptr) {
                m_netComm->HandleSocketBreak(socket);
            }
            return;
        }, tcpSocket);
    if (noticeThread.joinable()) {
        noticeThread.detach();
    }
}

/**
 * @功能描述：处理SOCKET中断事件
 * @参数 [in] breakSocket：断开的VmiSocket对象
 */
void NetComm::HandleSocketBreak(std::shared_ptr<VmiSocket> breakSocket)
{
    bool doNotify = false;
    {
        std::unique_lock<std::mutex> lockGuard(m_lock);
        if (breakSocket.get() == m_socket.get() && !m_isBroken) {
            m_isBroken = true;
            doNotify = true;
        }
    }
    // 通知socket异常断开
    if (doNotify) {
        if (m_breakCallback != nullptr) {
            m_breakCallback(shared_from_this());
        }
    }
}

/**
 * @功能描述：启动通信，启动流解析线程和心跳
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::Start()
{
    std::unique_lock<std::mutex> lockGuard(m_lock);
    if (m_status == NET_COMM_STATUS_RUNNING) {
        NC_ERR("alreay running");
        return true;
    } else if (m_status == NET_COMM_STATUS_UNINIT) {
        NC_ERR("has not init");
        return false;
    }

    if (m_mode == NetComm::CLIENT) {
        return StartInClientMode();
    } else {
        return StartInServerMode();
    }
}

/**
 * @功能描述：启动通信（Server模式）
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::StartInServerMode()
{
    NC_INFO("begin to Start in server mode");
    bool result = false;

    do {
        m_isBroken = false;

        // 设置发送和接收超时
        m_socket->SetSocketOption(SOCKET_OPTION_BITSET_NODELAY | SOCKET_OPTION_BITSET_QUICKACK);
        m_socket->SetSendTimeout(1, 0);
        m_socket->SetRecvTimeout(1, 0);
        m_socket->SetEventNotice(std::dynamic_pointer_cast<VmiEventNotice>(m_notice));
        NC_INFO("new socket setEventNotice");

        if (!StartStreamParseAndHeartbeat()) {
            break;
        }

        result = true;
        m_status = NET_COMM_STATUS_RUNNING;
    } while (0);

    if (!result) {
        NC_ERR("Start failed");
        StopNoLock();
    }

    NC_INFO("Start successed");
    return result;
}

/**
 * @功能描述：启动通信（Client模式）
 * @返回值：成功返回true，失败返回false
 */
bool NetComm::StartInClientMode()
{
    NC_INFO("begin to Start in client mode");
    bool isSuccess = false;

    do {
        m_isBroken = false;

        NC_INFO("try connecting to server");
        int connectResult = m_socket->Connect();
        if (connectResult != 0) {
            NC_ERR("error: setup connection to server failed");
            break;
        }
        m_socket->SetEventNotice(std::dynamic_pointer_cast<VmiEventNotice>(m_notice));
        NC_INFO("connected to server, socket:%p, sockfd:%d", m_socket.get(), m_socket->GetFd());

        if (!StartStreamParseAndHeartbeat()) {
            break;
        }

        isSuccess = true;
        m_status = NET_COMM_STATUS_RUNNING;
    } while (0);

    if (!isSuccess) {
        NC_ERR("Start failed");
        StopNoLock();
    }

    NC_INFO("Start successed");
    return isSuccess;
}

/**
 * @功能描述：停止网络通信（加锁）
 */
void NetComm::Stop()
{
    NC_INFO("Stop begin");
    std::unique_lock<std::mutex> lockGuard(m_lock);
    StopNoLock();
    NC_INFO("Stop end");
}

/**
 * @功能描述：停止网络通信（不加锁），停止心跳、解析线程，关闭Socket
 */
void NetComm::StopNoLock()
{
    // 关闭socket
    if (m_socket != nullptr) {
        m_socket->SetEventNotice(nullptr);
        m_socket->CloseSocket();
        NC_INFO("Security Audit: close client socket");
    }

    // 停止心跳线程
    if (m_heartbeat != nullptr) {
        NC_INFO("heartbeat begin stop");
        m_heartbeat->ForceStop();
        NC_INFO("Security Audit: heartbeat ForceStop");
    }

    // 停止并销毁StreamParseThread
    if (m_streamParseThread != nullptr) {
        NC_INFO("stream parse thread begin stop");
        m_streamParseThread->Stop();
        m_streamParseThread = nullptr;
        NC_INFO("Security Audit: stream parser thread stopped and destroy");
    }

    // 销毁心跳
    if (m_heartbeat != nullptr) {
        if (m_streamParser != nullptr) {
            m_streamParser->SetServiceHandle(VMIMsgType::HEARTBEAT, nullptr);
        }
        m_heartbeat = nullptr;
        NC_INFO("delete m_heartbeat");
    }

    for (uint8_t type = VMIMsgType::HEARTBEAT; type < VMIMsgType::End; ++type) {
        if (m_pktHandle[type] != nullptr) {
            m_pktHandle[type]->ClearQueue();
            NC_INFO("%u stream clear", type);
        }
    }

    if (m_status == NET_COMM_STATUS_RUNNING) {
        m_status = NET_COMM_STATUS_INIT;
    }
}

/**
 * @功能描述：清理、释放分配的对象和资源（加锁）
 */
void NetComm::Deinit()
{
    NC_INFO("Deinit begin");
    std::unique_lock<std::mutex> lockGuard(m_lock);
    DeinitNoLock();
    NC_INFO("Deinit end");
}

/**
 * @功能描述：清理、释放分配的对象和资源（不加锁）
 */
void NetComm::DeinitNoLock()
{
    StopNoLock();

    for (uint8_t type = 0; type < VMIMsgType::End; ++type) {
        if (m_pktHandle[type] != nullptr) {
            if (m_streamParser != nullptr) {
                m_streamParser->SetServiceHandle(static_cast<VMIMsgType>(type), nullptr);
            }
            m_pktHandle[type] = nullptr;
            NC_INFO("%u stream destroyed", type);
        }
    }

    // 销毁socket
    if (m_socket != nullptr) {
        m_socket = nullptr;
        NC_INFO("client socket destroyed");
    }

    if (m_notice != nullptr) {
        m_notice = nullptr;
    }

    if (m_streamParser != nullptr) {
        delete m_streamParser;
        m_streamParser = nullptr;
    }
    m_status = NET_COMM_STATUS_UNINIT;
}

/**
 * @功能描述：清空指定类型的消息队列
 * @参数 [in] type：消息类型
 */
void NetComm::ClearQueue(VMIMsgType type)
{
    std::unique_lock<std::mutex> lockGuard(m_lock);
    if (type > VMIMsgType::Invalid && type < VMIMsgType::End) {
        if (m_pktHandle[type] != nullptr) {
            m_pktHandle[type]->ClearQueue();
            NC_INFO("clear queue data: %u", type);
        }
    }
}

/**
 * @功能描述：发送type类型的数据
 * @参数 [in] type：数据的消息类型
 * @参数 [in] dataPair：数据的地址和大小pair
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t NetComm::Send(VMIMsgType type, const std::pair<uint8_t *, uint32_t>& dataPair)
{
    if (type <= VMIMsgType::Invalid || type >= VMIMsgType::End) {
        NC_ERR("error: invalid msg type: %u", type);
        return VMI_INSTRUCTION_ENGINE_INVALID_PARAM;
    }

    uint8_t *data = dataPair.first;
    uint32_t length = dataPair.second;

    if (data == nullptr || length == 0) {
        NC_ERR("error: Invalid paramter, data:%p, length:%u", data, length);
        return VMI_INSTRUCTION_ENGINE_INVALID_PARAM;
    }

    if (m_socket == nullptr) {
        NC_ERR("error: uninitialize socket");
        return VMI_INSTRUCTION_ENGINE_UNINIT_SOCK;
    }

    auto message = new (std::nothrow) uint8_t[length + sizeof(StreamMsgHead)];
    if (message == nullptr) {
        NC_ERR("error: alloc failed!");
        return VMI_INSTRUCTION_ENGINE_SEND_ALLOC_FAILED;
    }

    errno_t rc = memset_s(message, length + sizeof(StreamMsgHead), 0, length + sizeof(StreamMsgHead));
    if (rc != EOK) {
        NC_ERR("error: memset failed, rc:%d", rc);
        delete []message;
        return VMI_INSTRUCTION_ENGINE_SEND_MEMSET_FAILED;
    }

    rc = memcpy_s(message + sizeof(StreamMsgHead), length, data, length);
    if (rc != EOK) {
        NC_ERR("error: memcpy failed, rc:%d", rc);
        delete []message;
        return VMI_INSTRUCTION_ENGINE_SEND_MEMCPY_FAILED;
    }

    int ret = m_fragments[type].FragmentSend(type, m_socket,
        *(reinterpret_cast<StreamMsgHead *>(message)), length);

    delete []message;

    if (static_cast<size_t>(ret) == length) {
        return VMI_SUCCESS0;
    } else {
        NC_ERR("error: fragment send failed, ret:%d, socket:%p, socketfd:%d",
            ret, m_socket.get(), (m_socket != nullptr) ? m_socket->GetFd() : 0);
        return VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    }
}

/**
 * @功能描述：发送type类型的数据
 * @参数 [in] type：数据的消息类型
 * @参数 [in] pkt：StreamMsgHead包头引用，之后是数据
 * @参数 [in] dataSize：数据大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t NetComm::Send(VMIMsgType type, StreamMsgHead& pkt, uint32_t dataSize)
{
    if (type <= VMIMsgType::Invalid || type >= VMIMsgType::End) {
        NC_ERR("error: invalid msg type: %u", type);
        return VMI_INSTRUCTION_ENGINE_INVALID_PARAM;
    }

    int ret = m_fragments[type].FragmentSend(type, m_socket, pkt, dataSize);

    if (static_cast<size_t>(ret) == dataSize) {
        return VMI_SUCCESS0;
    } else {
        NC_ERR("error: fragment send failed, ret:%d, socket:%p, socketfd:%d",
            ret, m_socket.get(), (m_socket != nullptr) ? m_socket->GetFd() : 0);
        return VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    }
}

/**
 * @功能描述：设置是否整包发送，不走分片流程
 * @参数 [in] type：数据类型
 * @参数 [in] flag：true表示无论数据多大都整包发送，否则false
 */
void NetComm::SetSingleFragment(VMIMsgType type, bool flag)
{
    if (type <= VMIMsgType::Invalid || type >= VMIMsgType::End) {
        NC_ERR("error: SetSingleFragment invalid msg type: %u", type);
        return;
    }

    m_fragments[type].SetSingleSend(flag);
}

std::shared_ptr<NetComm> g_instStreamNetComm = nullptr;
std::shared_ptr<NetComm> g_videoStreamNetComm = nullptr;

/**
 * @功能描述：设置指令流的通信组件
 * @参数 [in] netComm：通信组件
 */
void SetInstructionStreamNetComm(std::shared_ptr<NetComm> netComm)
{
    g_instStreamNetComm = netComm;
}

/**
 * @功能描述：设置视频流的通信组件
 * @参数 [in] netComm：通信组件
 */
void SetVideoStreamNetComm(std::shared_ptr<NetComm> netComm)
{
    g_videoStreamNetComm = netComm;
}

/**
 * @功能描述：发送GL指令数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendGLData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::GL, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送视频数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendVideoData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::Video, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送音频数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendAudioData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::Audio, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送录音数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendRecorderData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::Recorder, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送触控输入数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendTouchInputData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::TouchInput, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送输入法数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendIMEData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::InputMethodEditor, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送传感器数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendSensorData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::Sensor, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送GPS数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendGpsData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::GPS, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送屏幕旋转方向数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendOrientationData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::ORIENTATION, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送游戏控制数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendGameControlData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::GameControl, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送RPC数据
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendRPCData(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_instStreamNetComm != nullptr) {
        ret = g_instStreamNetComm->Send(VMIMsgType::ClientRPC, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：发送编码模式和编码参数
 * @参数 [in] data：数据的地址
 * @参数 [in] length：数据的大小
 * @返回值：成功返回VMI_SUCCESS，失败返回错误码
 */
uint32_t SendCloudPhoneEncoderConf(uint8_t *data, size_t length)
{
    uint32_t ret = VMI_INSTRUCTION_ENGINE_SEND_FAIL;
    if (g_videoStreamNetComm != nullptr) {
        ret = g_videoStreamNetComm->Send(VMIMsgType::VideoEncodeConf, std::pair<uint8_t *, uint32_t>(data, length));
    }
    return ret;
}

/**
 * @功能描述：注册GL指令的数据处理钩子函数（只在客户端用）
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterGLDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
#if defined(USE_GL_PACKET_HANDLE)
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterGLDataHook(hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
#else
    (void)hook;
    ERR("error: USE_GL_PACKET_HANDLE macro has not defined!");
    return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
#endif
}

/**
 * @功能描述：注册视频数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterVideoDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::Video, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册音频数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterAudioDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::Audio, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册录音数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterRecorderDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::Recorder, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册触控输入数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterTouchInputDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::TouchInput, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册输入法数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterImeDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::InputMethodEditor, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册传感器数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterSensorDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::Sensor, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册GPS数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterGpsDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::GPS, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册屏幕旋转方向数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterOrientationDataHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::ORIENTATION, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册VideoStreamH264数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterVideoStreamH264HandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    uint32_t ret = VMI_SUCCESS0;
    if (g_videoStreamNetComm != nullptr) {
        ret = g_videoStreamNetComm->RegisterHook(VMIMsgType::VideoStreamH264, hook, true);
        return ret;
    } else {
        ERR("error: g_videoStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册VideoEncodeStatistics数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterVideoStreamEncodeStatisticsHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    uint32_t ret = VMI_SUCCESS0;
    if (g_videoStreamNetComm != nullptr) {
        ret = g_videoStreamNetComm->RegisterHook(VMIMsgType::VideoEncodeStatistics, hook, false);
        return ret;
    } else {
        ERR("error: g_videoStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册游戏控制数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterGameControlHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::GameControl, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}

/**
 * @功能描述：注册RPC数据处理钩子函数
 * @参数 [in] hook：钩子函数地址
 * @返回值：成功返回VMI_SUCCESS，失败返回VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL
 */
uint32_t RegisterRPCHandleHook(RENDER_SERVER_HANDLE_HOOK hook)
{
    if (g_instStreamNetComm != nullptr) {
        return g_instStreamNetComm->RegisterHook(VMIMsgType::ClientRPC, hook, false);
    } else {
        ERR("error: g_instStreamNetComm is nullptr");
        return VMI_INSTRUCTION_ENGINE_HOOK_REGISTER_FAIL;
    }
}
